import type { MetaFunction } from "@remix-run/node";
import {
    Links,
    LiveReload,
    Meta,
    Outlet,
    Scripts,
    ScrollRestoration,
} from "@remix-run/react";
import React from "react";

import { GitHubBanner, Refine } from "@refinedev/core";
import { RefineSnackbarProvider, notificationProvider } from "@refinedev/mui";

import { RefineKbar, RefineKbarProvider } from "@refinedev/kbar";
import routerProvider, {
    UnsavedChangesNotifier,
} from "@refinedev/remix-router";

import { withEmotionCache } from "@emotion/react";
// eslint-disable-next-line no-restricted-imports
import { unstable_useEnhancedEffect as useEnhancedEffect } from "@mui/material";
import dataProvider from "@refinedev/simple-rest";
import { authProvider } from "~/authProvider";
import { ClientStyleContext } from "~/contexts/ClientStyleContext";

const API_URL = "https://api.fake-rest.refine.dev";

export const meta: MetaFunction = () => ({
    charset: "utf-8",
    title: "Remix + Refine + Material UI App",
    viewport: "width=device-width,initial-scale=1",
});

interface DocumentProps {
    children: React.ReactNode;
    title?: string;
}

const Document = withEmotionCache(
    ({ children, title }: DocumentProps, emotionCache) => {
        const clientStyleData = React.useContext(ClientStyleContext);

        // Only executed on client
        useEnhancedEffect(() => {
            // re-link sheet container
            emotionCache.sheet.container = document.head;
            // re-inject tags
            const tags = emotionCache.sheet.tags;
            emotionCache.sheet.flush();
            tags.forEach((tag) => {
                // eslint-disable-next-line no-underscore-dangle
                (emotionCache.sheet as any)._insertTag(tag);
            });
            // reset cache to reapply global styles
            clientStyleData.reset();
        }, []);

        return (
            <html lang="en">
                <head>
                    <meta charSet="utf-8" />
                    <meta
                        name="viewport"
                        content="width=device-width,initial-scale=1"
                    />
                    {title ? <title>{title}</title> : null}
                    <Meta />
                    <Links />
                    <link
                        rel="stylesheet"
                        href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
                    />
                    <meta
                        name="emotion-insertion-point"
                        content="emotion-insertion-point"
                    />
                </head>
                <body>
                    {children}
                    <ScrollRestoration />
                    <Scripts />
                    <LiveReload />
                </body>
            </html>
        );
    },
);

// https://remix.run/api/conventions#default-export
// https://remix.run/api/conventions#route-filenames
export default function App() {
    return (
        <Document>
            <GitHubBanner />
            <RefineKbarProvider>
                <RefineSnackbarProvider>
                    <RefineKbarProvider>
                        <Refine
                            routerProvider={routerProvider}
                            dataProvider={dataProvider(API_URL)}
                            notificationProvider={notificationProvider}
                            authProvider={authProvider}
                            resources={[
                                {
                                    name: "blog_posts",
                                    list: "/blog-posts",
                                    create: "/blog-posts/create",
                                    edit: "/blog-posts/edit/:id",
                                    show: "/blog-posts/show/:id",
                                    meta: {
                                        canDelete: true,
                                    },
                                },
                            ]}
                            options={{
                                syncWithLocation: true,
                                warnWhenUnsavedChanges: true,
                            }}
                        >
                            <Outlet />
                            <UnsavedChangesNotifier />
                            <RefineKbar />
                        </Refine>
                    </RefineKbarProvider>
                </RefineSnackbarProvider>
            </RefineKbarProvider>
        </Document>
    );
}

export function links() {
    return [
        {
            rel: "stylesheet",
            href: "https://unpkg.com/modern-css-reset@1.4.0/dist/reset.min.css",
        },
    ];
}
